﻿using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using YaAppoint.Appointments.Pools;
using YaAppoint.ExamAppies;
using YaAppoint.OnlineServiceCache;
using YaAppoint.Response;
using YaAppoint.TextTemplates;

namespace YaAppoint.Appointments
{
    [RemoteService(isEnabled:false)]
    public class AppointmentAppService(IRepository<Pool, Guid> poolRepository,
                                       IRepository<ExamApplication, Guid> examApplicationRepository,
                                       IRepository<Appointment, Guid> appointmentRepository,
                                       IOnlineServiceCacheAppService onlineServiceCacheAppService,
                                       IMapper mapper,
                                       IRepository<TextTemplate, Guid> textTemplateRepository) : ApplicationService, IAppointmentAppService, ITransientDependency
    {
        private readonly IRepository<Pool, Guid> _poolRepository = poolRepository;
        private readonly IRepository<TextTemplate, Guid> _textTemplateRepository = textTemplateRepository;
        private readonly IRepository<Appointment, Guid> _appointmentRepository = appointmentRepository;
        private readonly IMapper _mapper = mapper;
        private readonly IRepository<ExamApplication, Guid> _examApplicationRepository = examApplicationRepository;
        private readonly IOnlineServiceCacheAppService _onlineServiceCacheAppService = onlineServiceCacheAppService;

        /// <summary>
        /// 申请项目预约状态改变，回写his
        /// </summary>
        public async Task ApplyExamItemStatusChangeToHis(List<ApplyExamItemStatusChangeDto> dtos)
        {
            var onlineService = await _textTemplateRepository.FirstOrDefaultAsync(t => t.Type == TemplateType.Service
                                                                                       && t.Interface != null
                                                                                       && t.Interface.Equals("IWriteBackToHisService")
                                                                                    && t.IsActive);
            if (onlineService != null && dtos.Count > 0)
            {
                // 从缓存中获取
                var cachedService =await _onlineServiceCacheAppService.GetOrAddOnlineService(_mapper.Map<TextTemplate, TextTemplateDto>(onlineService));
                if (cachedService.GetInstance() is IWriteBackToHisService service)
                {
                    await service.WiteBackAsync(dtos);
                }
            }
            return;
        }


        /// <summary>
        /// 生成编号
        /// </summary>
        /// <returns></returns>
        public string GeneratorNumber()
        {
            string timePart = DateTime.Now.ToString("yyMMddHHmmss");

            var _random = new Random();
            int random = _random.Next(0, 100);
            string randomPart = random.ToString("D2");
            return timePart + randomPart;
        }


        /// <summary>
        /// 创建预约
        /// 主要是"自动预约在用"
        /// </summary>
        /// <returns></returns>
        public async Task<AppointmentDto> CreateAppointment(List<ExamApplicationDto> applyItems, PoolDto poolDto,AppointmentStatus status)
        {
            var entity = new Appointment();
            entity.IsActive = true;
            entity.PoolId = poolDto.Id!.Value;
            List<Appointment> appointments = null;
            do
            {
                entity.Number = GeneratorNumber();
                appointments = await _appointmentRepository.GetListAsync(a => a.Number == entity.Number);
            }
            while (appointments.Count > 0);
            entity.Status = status;
            var pool = await _poolRepository.FirstOrDefaultAsync(p => p.Id == poolDto.Id);
            if (pool == null)
            {
                throw new BusinessException(CustomErrorCodes.PoolNotExist);
            }
            pool.Current += 1;
            await _poolRepository.UpdateAsync(pool);
            entity.Pool = pool;
            var idList = applyItems.Select(e => e.Id);
            var examApplicationItems = await _examApplicationRepository.GetListAsync(item => idList.Contains(item.Id));
            for (int i = 0; i < examApplicationItems.Count; i++)
            {
                examApplicationItems[i].AppointmentId = entity.Id;
                examApplicationItems[i].AppointmentInfo = entity.DisplayName;
            }
            entity.ExamApplications = examApplicationItems;
            await _appointmentRepository.InsertAsync(entity);
            await _examApplicationRepository.UpdateManyAsync(examApplicationItems);
            return _mapper.Map<Appointment, AppointmentDto>(entity);
        }

        /// <summary>
        /// 获取预约打印信息
        /// </summary>
        /// <param name="applyNumber"></param>
        /// <returns></returns>
        public async Task<BackJson> GetPrintData(string applyNumber)
        {
            var res = new BackJson();
            if (string.IsNullOrEmpty(applyNumber))
            {
                res.code = 2;
                res.msg = "Url参数applyNumbers为空。";
            }
            else
            {
                var numberList = applyNumber.Split(',').ToList();
                // 获取申请单对应检查项目
                var applyItems = await examApplicationRepository.GetListAsync(applyItem => numberList.Contains(applyItem.ApplyNumber));
                applyItems.DistinctBy(item => item.AppointmentId).ToList();
                var appointmentIds = applyItems.Select(item => item.AppointmentId);
                var appointmentList = await _appointmentRepository.GetListAsync(a => appointmentIds.Contains(a.Id));
                res.code = 0;
                res.data = _mapper.Map<List<Appointment>, List<AppointmentDto>>(appointmentList);
            }
            return res;
        } 
    }
}
